package xutil

import (
	"os"
	"sync"

	"gitee.com/wosylf/ltool/alipay"
)

type AlipayApp struct {
	Id            int64  `gorm:"primarykey"  json:"id" form:"id"`
	CreatedAt     int64  `gorm:"autoCreateTime" json:"created_at" form:"created_at"`
	Aid           int64  `gorm:"size:32;comment:归属id" json:"aid" form:"aid"`                                              //归属id
	Name          string `gorm:"type:varchar(25);comment:支付渠道名" json:"name,omitempty"`                                    //支付宝应用私钥
	Zappid        string `gorm:"type:varchar(25);comment:子商户号,mid" json:"zappid,omitempty"`                               //支付宝应用私钥,,银商是mid
	Appid         string `gorm:"index;type:varchar(18);comment:appid,tid" json:"appid,omitempty"`                         //银盛是商户id,银商是tid
	AliPrivateKey string `gorm:"type:varchar(2000);comment:支付宝应用私钥,key" json:"ali_private_key,omitempty"`                 //支付宝应用私钥
	AliPubKey     string `gorm:"type:varchar(500);comment:支付宝应用公钥,额度" json:"ali_pub_key,omitempty"`                       //支付宝应用私钥，基本固定长度392
	AliContentKey string `gorm:"type:varchar(25);comment:支付宝应用私钥,前缀" json:"ali_content_key,omitempty"`                    //支付宝应用私钥
	Pwd           string `gorm:"type:varchar(25);comment:证书密码,第几轮" json:"pwd,omitempty"`                                  //支付宝应用私钥
	Pfx           string `gorm:"type:varchar(56);comment:pfx证书" json:"pfx,omitempty"`                                     //银盛的pfx证书
	AliRas2       string `gorm:"type:varchar(56);comment:应用公钥证书alipayCertPublicKey_RSA2,appid" json:"ali_ras2,omitempty"` //应用公钥证书alipayCertPublicKey_RSA2
	AliPublicCer  string `gorm:"type:varchar(56);comment:支付宝公钥证书PublicKey_202100" json:"ali_public_cer,omitempty"`        //支付宝公钥证书PublicKey_202100
	AliRootCer    string `gorm:"type:varchar(56);comment:支付宝根证书！文件名一般为alipayRootCert" json:"ali_root_cer,omitempty"`      //支付宝根证书！文件名一般为alipayRootCert.crt
	Istest        int8   `gorm:"comment:'istest';"  json:"istest" form:"istest"`                                          //是否为测试模式，如果为测试，只给0.1元
	//AliPayeeUserId    string `gorm:"type:varchar(32);comment:'收款账户的支付宝用户号。'" json:"ali_payee_user_id,omitempty"`           //收款账户的支付宝用户号。
	AliPublicCerValue []byte         `gorm:"-" json:"-"` //支付宝应用私钥文件里的内容
	AliRas2Value      []byte         `gorm:"-" json:"-"` //应用公钥证书alipayCertPublicKey_RSA2文件里的内容
	AliRootCerValue   []byte         `gorm:"-" json:"-"` //应用公钥证书alipayCertPublicKey_RSA2文件里的内容
	Domain            string         `gorm:"-" json:"domain,omitempty"`
	Ali               *alipay.Client `gorm:"-" json:"-"`
}

// args，第一个参数为回调域名，第二个为回调路径，第三个如果有就是返回路径
func (a *AlipayApp) F获取支付宝链接(args ...string) (cli *alipay.Client, err error) {
	if a.Ali != nil {
		return a.Ali, nil
	}
	if a.AliPublicCer != "" {
		AliPublicCerValue, err1 := os.ReadFile(a.AliPublicCer)
		if err1 != nil {
			return nil, err1
		}
		AliRas2Value, err1 := os.ReadFile(a.AliRas2)
		if err1 != nil {
			return nil, err1
		}
		AliRootCerValue, err1 := os.ReadFile(a.AliRootCer)
		if err1 != nil {
			return nil, err1
		}
		if cli, err = alipay.F新建链接(a.AliPrivateKey, AliPublicCerValue, AliRootCerValue, AliRas2Value); err != nil {
			return
		}
	} else {
		/* if cli, err = alipay.F新建支付宝链接(appid, ali.AliPrivateKey); err != nil {
			return
		} */
	}
	domain := ""
	l := len(args)
	if l > 0 {
		domain = args[0]
	}
	if domain != "" {
		if l > 1 { //回调地址，这个估计必传的
			cli.NotifyUrl = domain + args[1]
		}
		if l > 2 { //h5返回地址
			cli.ReturnUrl = domain + args[2]
		}
	}
	//client.AliContentKey = app.AliContentKey
	cli.AppId = a.Appid
	a.Ali = cli
	return
}

type V支付结构 struct {
	S map[interface{}]*AlipayApp
	L sync.RWMutex
}

var V支付 *V支付结构

func init() {
	V支付 = &V支付结构{
		S: make(map[interface{}]*AlipayApp),
	}

}

// 默认是搜索id，如果是appid，那么传appid
func (a *V支付结构) F获取支付配置(id interface{}, fn func(ali *AlipayApp) (err error)) (ali *AlipayApp, err error) {
	var ok bool
	a.L.RLock()
	ali, ok = a.S[id]
	if ok {
		a.L.RUnlock()
		return
	}
	a.L.RUnlock()
	a.L.Lock()
	defer a.L.Unlock()
	ali = new(AlipayApp)
	if err = fn(ali); err != nil {
		return
	}
	a.S[id] = ali
	a.S[ali.Appid] = ali
	return
}
